import com.sun.jna.Pointer;

///A chess piece
class Piece
{
	public final static int COLOR_WHITE = 0;
	public final static int COLOR_BLACK = 1;
	
	public final static int TYPE_KING = 2;
	public final static int TYPE_QUEEN = 3;
	public final static int TYPE_BISHOP = 4;
	public final static int TYPE_ROOK = 5;
	public final static int TYPE_KNIGHT = 6;
	public final static int TYPE_PAWN = 7;
	
	private Pointer ptr;
	private int ID;
	private int iteration;
	
	public Piece(Pointer p) {
		ptr = p;
		ID = Client.INSTANCE.pieceGetId(ptr);
		iteration = BaseAI.iteration;
	}
	
	boolean validify() {
		if(iteration == BaseAI.iteration) return true;
		for(int i = 0; i < BaseAI.pieces.length; i++) {
			if(BaseAI.pieces[i].ID == ID) {
				ptr = BaseAI.pieces[i].ptr;
				iteration = BaseAI.iteration;
				return true;
			}
		}
		throw new ExistentialError();
	}

	//commands

	///
	int move(int file, int rank, int type) {
		validify();
		return Client.INSTANCE.pieceMove(ptr, file, rank, type);
	}

	//getters

	///Unique Identifier
	public int getId()
	{
		validify();
		return Client.INSTANCE.pieceGetId(ptr);
	}
	
	///The owner of the piece
	private int getOwner() {
		validify();
		return Client.INSTANCE.pieceGetOwner(ptr);
	}
	
	public int getColor() {
		int owner = getOwner();
		return (owner == 0 ? COLOR_WHITE : COLOR_BLACK);
	}
	
	///The letter this piece is at (1-8)
	public int getFile(){
		validify();
		return Client.INSTANCE.pieceGetFile(ptr);
	}
	
	///The number this piece is at (1-8)
	public int getRank(){
		validify();
		return Client.INSTANCE.pieceGetRank(ptr);
	}
	
	///1=has moved, 0=has not moved
	private int getHasMoved(){
		validify();
		return Client.INSTANCE.pieceGetHasMoved(ptr);
	}
	
	public boolean hasMoved(){
		return (getHasMoved() == 0 ? false : true);
	}
	
	///The letter that describes this piece's type. K=King, Q=Queen, B=Bishop, N=Knight, R=Rook, P=Pawn
	private int getType(){
		validify();
		return Client.INSTANCE.pieceGetType(ptr);
	}
	
	public int getKind(){
		int type = getType();
		
		//if piece is the king
		if(type == 'K') return TYPE_KING;
		//if piece is the queen
		else if(type == 'Q') return TYPE_QUEEN;
		//if piece is a bishop
		else if(type == 'B') return TYPE_BISHOP;
		//if piece is a knight
		else if(type == 'N') return TYPE_KNIGHT;
		//if piece is a rook
		else if(type == 'R') return TYPE_ROOK;
		//if piece is a pawn
		else return TYPE_PAWN;
	}
	
	public String getKindString() {
		return new String() + (char) getType();
	}

	@Override
	public boolean equals(Object obj) {
		boolean equals = false;
		if (obj != null && obj instanceof Piece) {
			Piece that = (Piece) obj;
			equals = getFile() == that.getFile() && getRank() == that.getRank();
		}
		return equals;
	}

	@Override
	public int hashCode() {
		return String.valueOf(42 * getColor()).hashCode() + String.valueOf(42 * getKind()).hashCode();
	}
	
	@Override
	public String toString() {
		return Character.toString((char) getType());
	}

}
